#ifndef padl_VIC_H_
#define padl_VIC_H_

#include "target.h"


/* Vectored Interrupt Controller (VIC) */
#define VIC_BASE_ADDR	0xFFFFF000
#define VICIRQStatus   (*(volatile U32 *)(VIC_BASE_ADDR + 0x000))
#define VICFIQStatus   (*(volatile U32 *)(VIC_BASE_ADDR + 0x004))
#define VICRawIntr     (*(volatile U32 *)(VIC_BASE_ADDR + 0x008))
#define VICIntSelect   (*(volatile U32 *)(VIC_BASE_ADDR + 0x00C))
#define VICIntEnable   (*(volatile U32 *)(VIC_BASE_ADDR + 0x010))
#define VICIntEnClr    (*(volatile U32 *)(VIC_BASE_ADDR + 0x014))
#define VICSoftInt     (*(volatile U32 *)(VIC_BASE_ADDR + 0x018))
#define VICSoftIntClr  (*(volatile U32 *)(VIC_BASE_ADDR + 0x01C))
#define VICProtection  (*(volatile U32 *)(VIC_BASE_ADDR + 0x020))
#define VICSWPrioMask  (*(volatile U32 *)(VIC_BASE_ADDR + 0x024))

#define VICVectAddr0   (*(volatile U32 *)(VIC_BASE_ADDR + 0x100))
#define VICVectAddr1   (*(volatile U32 *)(VIC_BASE_ADDR + 0x104))
#define VICVectAddr2   (*(volatile U32 *)(VIC_BASE_ADDR + 0x108))
#define VICVectAddr3   (*(volatile U32 *)(VIC_BASE_ADDR + 0x10C))
#define VICVectAddr4   (*(volatile U32 *)(VIC_BASE_ADDR + 0x110))
#define VICVectAddr5   (*(volatile U32 *)(VIC_BASE_ADDR + 0x114))
#define VICVectAddr6   (*(volatile U32 *)(VIC_BASE_ADDR + 0x118))
#define VICVectAddr7   (*(volatile U32 *)(VIC_BASE_ADDR + 0x11C))
#define VICVectAddr8   (*(volatile U32 *)(VIC_BASE_ADDR + 0x120))
#define VICVectAddr9   (*(volatile U32 *)(VIC_BASE_ADDR + 0x124))
#define VICVectAddr10  (*(volatile U32 *)(VIC_BASE_ADDR + 0x128))
#define VICVectAddr11  (*(volatile U32 *)(VIC_BASE_ADDR + 0x12C))
#define VICVectAddr12  (*(volatile U32 *)(VIC_BASE_ADDR + 0x130))
#define VICVectAddr13  (*(volatile U32 *)(VIC_BASE_ADDR + 0x134))
#define VICVectAddr14  (*(volatile U32 *)(VIC_BASE_ADDR + 0x138))
#define VICVectAddr15  (*(volatile U32 *)(VIC_BASE_ADDR + 0x13C))
#define VICVectAddr16  (*(volatile U32 *)(VIC_BASE_ADDR + 0x140))
#define VICVectAddr17  (*(volatile U32 *)(VIC_BASE_ADDR + 0x144))
#define VICVectAddr18  (*(volatile U32 *)(VIC_BASE_ADDR + 0x148))
#define VICVectAddr19  (*(volatile U32 *)(VIC_BASE_ADDR + 0x14C))
#define VICVectAddr20  (*(volatile U32 *)(VIC_BASE_ADDR + 0x150))
#define VICVectAddr21  (*(volatile U32 *)(VIC_BASE_ADDR + 0x154))
#define VICVectAddr22  (*(volatile U32 *)(VIC_BASE_ADDR + 0x158))
#define VICVectAddr23  (*(volatile U32 *)(VIC_BASE_ADDR + 0x15C))
#define VICVectAddr24  (*(volatile U32 *)(VIC_BASE_ADDR + 0x160))
#define VICVectAddr25  (*(volatile U32 *)(VIC_BASE_ADDR + 0x164))
#define VICVectAddr26  (*(volatile U32 *)(VIC_BASE_ADDR + 0x168))
#define VICVectAddr27  (*(volatile U32 *)(VIC_BASE_ADDR + 0x16C))
#define VICVectAddr28  (*(volatile U32 *)(VIC_BASE_ADDR + 0x170))
#define VICVectAddr29  (*(volatile U32 *)(VIC_BASE_ADDR + 0x174))
#define VICVectAddr30  (*(volatile U32 *)(VIC_BASE_ADDR + 0x178))
#define VICVectAddr31  (*(volatile U32 *)(VIC_BASE_ADDR + 0x17C))

#define VICVectAddress(n)	(*(volatile U32 *)(VIC_BASE_ADDR + 0x100 + (n*4)))

/* LPC23xx/24xx VICVectPriority(x)". */
#define VICVectPriority0   (*(volatile U32 *)(VIC_BASE_ADDR + 0x200))
#define VICVectPriority1   (*(volatile U32 *)(VIC_BASE_ADDR + 0x204))
#define VICVectPriority2   (*(volatile U32 *)(VIC_BASE_ADDR + 0x208))
#define VICVectPriority3   (*(volatile U32 *)(VIC_BASE_ADDR + 0x20C))
#define VICVectPriority4   (*(volatile U32 *)(VIC_BASE_ADDR + 0x210))
#define VICVectPriority5   (*(volatile U32 *)(VIC_BASE_ADDR + 0x214))
#define VICVectPriority6   (*(volatile U32 *)(VIC_BASE_ADDR + 0x218))
#define VICVectPriority7   (*(volatile U32 *)(VIC_BASE_ADDR + 0x21C))
#define VICVectPriority8   (*(volatile U32 *)(VIC_BASE_ADDR + 0x220))
#define VICVectPriority9   (*(volatile U32 *)(VIC_BASE_ADDR + 0x224))
#define VICVectPriority10  (*(volatile U32 *)(VIC_BASE_ADDR + 0x228))
#define VICVectPriority11  (*(volatile U32 *)(VIC_BASE_ADDR + 0x22C))
#define VICVectPriority12  (*(volatile U32 *)(VIC_BASE_ADDR + 0x230))
#define VICVectPriority13  (*(volatile U32 *)(VIC_BASE_ADDR + 0x234))
#define VICVectPriority14  (*(volatile U32 *)(VIC_BASE_ADDR + 0x238))
#define VICVectPriority15  (*(volatile U32 *)(VIC_BASE_ADDR + 0x23C))
#define VICVectPriority16  (*(volatile U32 *)(VIC_BASE_ADDR + 0x240))
#define VICVectPriority17  (*(volatile U32 *)(VIC_BASE_ADDR + 0x244))
#define VICVectPriority18  (*(volatile U32 *)(VIC_BASE_ADDR + 0x248))
#define VICVectPriority19  (*(volatile U32 *)(VIC_BASE_ADDR + 0x24C))
#define VICVectPriority20  (*(volatile U32 *)(VIC_BASE_ADDR + 0x250))
#define VICVectPriority21  (*(volatile U32 *)(VIC_BASE_ADDR + 0x254))
#define VICVectPriority22  (*(volatile U32 *)(VIC_BASE_ADDR + 0x258))
#define VICVectPriority23  (*(volatile U32 *)(VIC_BASE_ADDR + 0x25C))
#define VICVectPriority24  (*(volatile U32 *)(VIC_BASE_ADDR + 0x260))
#define VICVectPriority25  (*(volatile U32 *)(VIC_BASE_ADDR + 0x264))
#define VICVectPriority26  (*(volatile U32 *)(VIC_BASE_ADDR + 0x268))
#define VICVectPriority27  (*(volatile U32 *)(VIC_BASE_ADDR + 0x26C))
#define VICVectPriority28  (*(volatile U32 *)(VIC_BASE_ADDR + 0x270))
#define VICVectPriority29  (*(volatile U32 *)(VIC_BASE_ADDR + 0x274))
#define VICVectPriority30  (*(volatile U32 *)(VIC_BASE_ADDR + 0x278))
#define VICVectPriority31  (*(volatile U32 *)(VIC_BASE_ADDR + 0x27C))

#define VICVectPriority(n)	(*(volatile U32 *)(VIC_BASE_ADDR + 0x200 + (n*4)))

#define VICVectAddr    (*(volatile U32 *)(VIC_BASE_ADDR + 0xF00))

/// Interrupt sources //////////////////////////////////
#define	WDT_INT			0
#define SWI_INT			1
#define ARM_CORE0_INT	2
#define	ARM_CORE1_INT	3
#define	TIMER0_INT		4
#define TIMER1_INT		5
#define UART0_INT		6
#define	UART1_INT		7
#define	PWM0_1_INT		8
#define I2C0_INT		9
#define SPI0_INT		10			/* SPI and SSP0 share VIC slot */
#define SSP0_INT		10
#define	SSP1_INT		11
#define	PLL_INT			12
#define RTC_INT			13
#define EINT0_INT		14
#define EINT1_INT		15
#define EINT2_INT		16
#define EINT3_INT		17
#define	ADC0_INT		18
#define I2C1_INT		19
#define BOD_INT			20
#define EMAC_INT		21
#define USB_INT			22
#define CAN_INT			23
#define MCI_INT			24
#define GPDMA_INT		25
#define TIMER2_INT		26
#define TIMER3_INT		27
#define UART2_INT		28
#define UART3_INT		29
#define I2C2_INT		30
#define I2S_INT			31
////////////////////////////////////////////////////////

#define padl_vic_INSTALL_IRQ(interruptSource, irqHandlerFunction, priority)	\
	VICIntEnClr = 1 << interruptSource;\
	VICVectAddress(interruptSource) = (U32)irqHandlerFunction;\
	VICVectPriority(interruptSource) = priority;\
	VICIntEnable = 1 << interruptSource;

#define padl_vic_IS_ENABLE_INTERRUPT(n)	(VICIntEnable & (1 << interruptSource))
#define padl_vic_ENABLE_INTERRUPT(n)		(VICIntEnable = 1 << interruptSource)
#define padl_vic_DISABLE_INTERRUPT(n)	(VICIntEnClr = 1 << interruptSource)

// Obs.: Must be called at the end of interrupt routine
#define padl_vic_ACKNOWLEDGE_INTERRUPT()	(VICVectAddr = 0)

#endif /*padl_VIC_H_*/
